/*******************************************************************/
/* @ All Rights Reserved Copyright (C) 2014 broada,Co.,Ltd.        */
/*                                                                 */
/*  NAME      = frct_comm.h                                        */
/*  NOTE      = conntrack公用                                      */
/*  DATE      = 2014/10/28                                         */
/*******************************************************************/

#include <stdio.h>
#include <unistd.h>

#include "frct_comm.h"


L7_analyzer *frct_get_L7analyzer(Conntrack *p_st_ct)
{
    if(p_st_ct == NULL)
        return NULL;

    return &p_st_ct->st_l7_analyzer;
}


L7_transaction *frct_get_L7transaction(Conntrack *p_st_ct)
{
    if(p_st_ct == NULL)
        return NULL;
    
    return p_st_ct->st_l7_analyzer.p_st_transaction;
}


L7_session *frct_get_session(Conntrack *p_st_ct)
{
    if(p_st_ct == NULL)
        return NULL;

    return p_st_ct->st_l7_analyzer.p_st_session;
}


char *frct_get_session_username(L7_session *p_st_session)
{
    if(p_st_session == NULL)
        return NULL;

    return p_st_session->p_username;
}


int frct_set_session_username(L7_session *p_st_session, const char *p_username)
{
    char *p_name_tmp;
    if(p_st_session == NULL || p_username == NULL )
        return FR_FAIL;
    
    p_name_tmp = frstrdup(p_username);
    if(p_name_tmp == NULL)
        return FR_FAIL;
    
    if(p_st_session->p_username)
        frfree(p_st_session->p_username);
    
    p_st_session->p_username = p_name_tmp;

    return FR_SUCC;
}


void frct_free_session_username(L7_session *p_st_session)
{
    if(p_st_session == NULL)
        return;

    if(p_st_session->p_username)
    {
        frfree(p_st_session->p_username);
        p_st_session->p_username = NULL;
    }
    return;
}


struct timeval *frct_get_session_starttime(L7_session *p_st_session)
{
    if(p_st_session == NULL)
        return NULL;

    return &p_st_session->st_session_starttime;
}


int frct_set_session_starttime(L7_session *p_st_session, struct timeval *p_st_starttime)
{
    if(p_st_session == NULL || p_st_starttime == NULL )
        return FR_FAIL;
    
    p_st_session->st_session_starttime.tv_sec = p_st_starttime->tv_sec;
    p_st_session->st_session_starttime.tv_usec = p_st_starttime->tv_usec;

    return FR_SUCC;
}


struct timeval *frct_get_session_stoptime(L7_session *p_st_session)
{
    if(p_st_session == NULL)
        return NULL;

    return &p_st_session->st_session_stoptime;
}


int frct_set_session_stoptime(L7_session *p_st_session, struct timeval *p_st_stoptime)
{
    if(p_st_session == NULL || p_st_stoptime == NULL )
        return FR_FAIL;
    
    p_st_session->st_session_stoptime.tv_sec = p_st_stoptime->tv_sec;
    p_st_session->st_session_stoptime.tv_usec = p_st_stoptime->tv_usec;

    return FR_SUCC;
}


void *frct_get_session_private(L7_session *p_st_session)
{
    if(p_st_session == NULL)
        return NULL;

    return p_st_session->p_session_private;
}


int frct_set_session_private(L7_session *p_st_session, void *p_session_private)
{
    if(p_st_session == NULL || p_session_private == NULL )
        return 1;
    
    if(p_st_session->p_session_private)
        return 2;
    
    p_st_session->p_session_private = p_session_private;
    return 0;
}


int *frct_get_session_status(L7_session *p_st_session)
{
    if(p_st_session == NULL)
        return NULL;

    return &p_st_session->i_status;
}


int frct_set_session_status(L7_session *p_st_session, int i_status)
{
    if(p_st_session == NULL )
        return FR_FAIL;
    
    p_st_session->i_status = i_status;
    return FR_SUCC;
}


void frl7session_free(L7_module *p_st_l7_module, L7_session *p_st_l7_session)
{
    if(p_st_l7_session == NULL)
        return;
    
    if(p_st_l7_session->p_username)
    {
        frfree(p_st_l7_session->p_username);
        p_st_l7_session->p_username = NULL;
    }
    
    if(p_st_l7_session->p_session_private )
    {
        if( p_st_l7_module && p_st_l7_module->session_destory)
        {
            p_st_l7_module->session_destory(p_st_l7_session->p_session_private);
        }
        p_st_l7_session->p_session_private = NULL;
    }
    
    return;
}


void frl7trans_free(L7_transaction *p_st_l7_transaction)
{
    if(p_st_l7_transaction == NULL)
        return;
    
    if(p_st_l7_transaction->p_transaction_code)
    {
        frfree(p_st_l7_transaction->p_transaction_code);
        p_st_l7_transaction->p_transaction_code = NULL;
    }
    
    if(p_st_l7_transaction->p_transaction_title)
    {
        frfree(p_st_l7_transaction->p_transaction_title);
        p_st_l7_transaction->p_transaction_title = NULL;
    }

    if(p_st_l7_transaction->p_response_codestring)
    {
        frfree(p_st_l7_transaction->p_response_codestring);
        p_st_l7_transaction->p_response_codestring = NULL;
    }
    
    return;
}


int frct_get_direct_known(Conntrack *p_st_ct)
{
    if(p_st_ct == NULL)
        return FR_DIRECT_UNKNOWN;

    return p_st_ct->flg_direct_known;
}


int frcap_get_cs_direction(Conntrack *p_st_ct, u_int ui_ip, u_short us_port)
{
    if(p_st_ct == NULL)
        return FR_DIRECT_UNKNOWN;
    
    if(p_st_ct->dst_ip == ui_ip && p_st_ct->dst_port == us_port)
        return FR_SRV_IP_PORT;
    else if(p_st_ct->src_ip == ui_ip && p_st_ct->src_port == us_port)
        return FR_CLIENT_IP_PORT;
    else
        return FR_DIRECT_UNKNOWN;
}


int frcap_set_cs_srv(Conntrack *p_st_ct, u_int ui_srv_ip, u_short us_srv_port)
{
    char arr_mac[APM_MAC_SIZE];
    u_short us_tmp;
    u_int ui_tmp;
    
    if(p_st_ct == NULL)
        return FR_FAIL;
    
    if( !(p_st_ct->src_ip == ui_srv_ip && p_st_ct->src_port == us_srv_port)
        && !(p_st_ct->dst_ip == ui_srv_ip && p_st_ct->dst_port == us_srv_port) )
        return FR_FAIL;
    
    p_st_ct->flg_direct_known = FR_DIRECT_KNOWN;
    if( p_st_ct->dst_ip == ui_srv_ip && p_st_ct->dst_port == us_srv_port)
        return FR_SUCC;
    
    p_st_ct->flg_chg_direct = FR_YES;
    memcpy(arr_mac, p_st_ct->src_mac, sizeof(arr_mac));
    memcpy(p_st_ct->src_mac, p_st_ct->dst_mac, sizeof(p_st_ct->src_mac));
    memcpy(p_st_ct->dst_mac, arr_mac, sizeof(p_st_ct->dst_mac));
    
    ui_tmp = p_st_ct->src_ip;
    p_st_ct->src_ip = p_st_ct->dst_ip;
    p_st_ct->dst_ip = ui_tmp;
    
    us_tmp = p_st_ct->src_port;
    p_st_ct->src_port = p_st_ct->dst_port;
    p_st_ct->dst_port = us_tmp;

    return FR_SUCC;
}

int frct_has_master(Conntrack *p_st_ct)
{
    if(p_st_ct == NULL)
        return FR_NO;
    return p_st_ct->flg_has_master;
}

int frct_set_statIp(Conntrack *p_st_ct, u_short src_port, u_short dst_port)
{
    if(p_st_ct == NULL)
        return FR_FAIL;

    //逻辑上没有同时操作该字段的可能,不加锁也没问题
    //pthread_spin_lock(&p_st_ct->lock);
    p_st_ct->flg_chg_stat_ip = 2;
    p_st_ct->stat_src_port = src_port;
    p_st_ct->stat_dst_port = dst_port;
    //pthread_spin_unlock(&p_st_ct->lock);

    return FR_SUCC;
}

unsigned long frct_seq_increase(Conntrack *p_st_ct)
{
    if(p_st_ct == NULL)
        return 1;

    p_st_ct->ul_seq++;
    if(p_st_ct->ul_seq == 0)
        p_st_ct->ul_seq++;
    return p_st_ct->ul_seq;
}

void frct_drop_pcap(Conntrack *p_st_ct, short s_drop_pcap)
{
    if(p_st_ct == NULL)
        return;
    if(s_drop_pcap)
        p_st_ct->flg_drop_pcap = 1;
    else
        p_st_ct->flg_drop_pcap = 0;
    return;
}

